package com.cq.base.exception;

import java.text.MessageFormat;
import java.util.Locale;
import java.util.MissingResourceException;
import java.util.ResourceBundle;

public abstract class MessageException extends RuntimeException {
	private String message;
	private int errorCode = -1;

	public MessageException(int code) {
		errorCode = code;
		message = createMessage(code);
	}

	public MessageException(int code, Object... args) {
		errorCode = code;
		message = createMessage(code, args);
	}

	public MessageException(int code, Throwable cause) {
		super(cause);
		errorCode = code;
		message = createMessage(code);
	}

	public MessageException(int code, Throwable cause, Object... args) {
		super(cause);
		errorCode = code;
		message = createMessage(code, args);
	}

	protected abstract String getBundlePath();

	protected String createMessage(int code, Object... args) {
		String bundlePath = getBundlePath() + "-messages";
		ResourceBundle bundle = getBundle(bundlePath);
		String m = bundle.getString(String.valueOf(code));
		return code + "-" + MessageFormat.format(m, args);
	}

	/**
	 * @throws MissingResourceException if resource is missing
	 */
	protected static ResourceBundle getBundle(String bundlePath) {
		Locale locale = Locale.getDefault();
		ResourceBundle bundle = ResourceBundle.getBundle(bundlePath, locale);
		return bundle;
	}

	public int getErrorCode() {
		return errorCode;
	}

	public final String getMessage() {
		if (getCause() != null) {
			return message + " " + getCause().getMessage();
		} else {
			return message;
		}
	}

	protected void appendMessage(String s) {
		message += s;
	}

	protected void prependMessage(String s) {
		message = message + ". " + s;
	}

	public boolean equals(Object o) {
		if (this == o) {
			return true;
		}
		if (!(o instanceof MessageException)) {
			return false;
		}

		final MessageException exception = (MessageException) o;

		if (errorCode != exception.errorCode) {
			return false;
		}
		if (message != null ? !message.equals(exception.message) : exception.message != null) {
			return false;
		}

		return true;
	}

	public int hashCode() {
		int result;
		result = errorCode;
		result = 29 * result + (message != null ? message.hashCode() : 0);
		return result;
	}
}
